package gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;

import model.Job;
import model.Park;
import model.Role;
import model.User;
import controller.Controller;
/**
 * A JPanel that can display a list of jobs in a Calendar format.
 * @author James Gunter - jpgunter
 */
public class CalendarView extends JPanel implements ActionListener{

  private static final int PREFFERED_WIDTH = 800;
  private static final int PREFERRED_HEIGHT = 600;
  private JPanel[][] my_calendar_days;
  private Calendar my_cal;
  private JLabel my_current_month;
  private MainWindow my_parent;
  private Controller my_controller;
  private JButton my_prev_month_button;
  private JButton my_next_month_button;
  private JButton my_back_button;
  private JButton my_home_button;

  /**
   * Create the Panel.
   * @param the_parent
   * @param the_controller 
   */
  public CalendarView(MainWindow the_parent, Controller the_controller) {
    
    my_parent = the_parent;
    my_controller = the_controller;
    
    setPreferredSize(new Dimension(PREFFERED_WIDTH, PREFERRED_HEIGHT));
    setLayout(new BorderLayout(0, 0));
    
    JPanel nav_panel = new JPanel();
    nav_panel.setLayout(new BorderLayout());
    add(nav_panel, BorderLayout.NORTH);
    
    
    my_back_button = new JButton("Back");
    my_back_button.addActionListener(this);
    nav_panel.add(my_back_button, BorderLayout.WEST);
    
    my_current_month = new JLabel("February");
    my_current_month.setForeground(Color.BLUE);
    my_current_month.setFont(new Font("Dialog", Font.BOLD, 18));
    my_current_month.setHorizontalAlignment(SwingConstants.CENTER);
    nav_panel.add(my_current_month, BorderLayout.CENTER);
    
    my_home_button = new JButton("Home");
    my_home_button.addActionListener(this);
    nav_panel.add(my_home_button, BorderLayout.EAST);
    
    JPanel month_change_panel = new JPanel();
    month_change_panel.setLayout(new BorderLayout());
    add(month_change_panel, BorderLayout.SOUTH);
    
    my_prev_month_button = new JButton("<<Prev Month");
    my_prev_month_button.addActionListener(this);
    month_change_panel.add(my_prev_month_button, BorderLayout.WEST);
    
    JLabel my_total_jobs_label = new JLabel("Total Pending Jobs: " + my_controller.getPendingJobs().size());
    month_change_panel.add(my_total_jobs_label, BorderLayout.CENTER);
    
    my_next_month_button = new JButton("Next Month>>");
    my_next_month_button.addActionListener(this);
    month_change_panel.add(my_next_month_button, BorderLayout.EAST);
    
    JPanel calendar_panel = new JPanel();
    add(calendar_panel, BorderLayout.CENTER);
    calendar_panel.setLayout(new BorderLayout(0, 0));
    
    JPanel day_head_panel = new JPanel();
    calendar_panel.add(day_head_panel, BorderLayout.NORTH);
    day_head_panel.setLayout(new GridLayout(0, 7, 0, 0));
    
    JLabel sunday_label = new JLabel("Sunday");
    sunday_label.setHorizontalAlignment(SwingConstants.CENTER);
    day_head_panel.add(sunday_label);
    
    JLabel monday_label = new JLabel("Monday");
    monday_label.setHorizontalAlignment(SwingConstants.CENTER);
    day_head_panel.add(monday_label);
    
    JLabel tuesday_label = new JLabel("Tuesday");
    tuesday_label.setHorizontalAlignment(SwingConstants.CENTER);
    day_head_panel.add(tuesday_label);
    
    JLabel wednesday_label = new JLabel("Wednesday");
    wednesday_label.setHorizontalAlignment(SwingConstants.CENTER);
    day_head_panel.add(wednesday_label);
    
    JLabel thursday_label = new JLabel("Thursday");
    thursday_label.setHorizontalAlignment(SwingConstants.CENTER);
    day_head_panel.add(thursday_label);
    
    JLabel friday_label = new JLabel("Friday");
    friday_label.setHorizontalAlignment(SwingConstants.CENTER);
    day_head_panel.add(friday_label);
    
    JLabel saturday_label = new JLabel("Saturday");
    saturday_label.setHorizontalAlignment(SwingConstants.CENTER);
    day_head_panel.add(saturday_label);
    
    JPanel days_panel = new JPanel();
    calendar_panel.add(days_panel, BorderLayout.CENTER);
    days_panel.setLayout(new GridLayout(0, 7, 0, 0));
   
    my_cal = Calendar.getInstance();
    my_cal.add(Calendar.DATE, -1 * (my_cal.get(Calendar.DATE) - 1)); //go to the first day of the current month
    
    String month = (new SimpleDateFormat("MMMM").format(my_cal.getTime()));
    my_current_month.setText(month);
    
    int days_to_skip = getWeekdayNumber(my_cal.get(Calendar.DAY_OF_WEEK));
    int cur_month = my_cal.get(Calendar.MONTH);
    
    my_calendar_days = new JPanel[5][7];
    for(int i = 0 ; i < 5;i++){
      for(int j = 0; j < 7; j ++){
        my_calendar_days[i][j] = new JPanel();
        my_calendar_days[i][j].setLayout(new BorderLayout(0,2));
        if(days_to_skip == 0 && cur_month == my_cal.get(Calendar.MONTH)){
          my_calendar_days[i][j].add(new JLabel("" + my_cal.get(Calendar.DATE)), BorderLayout.NORTH);
          
          JPanel day_panel = new JPanel();
          day_panel.setLayout(new BoxLayout(day_panel, BoxLayout.PAGE_AXIS));
          for(final Job job : my_controller.getJobs(my_cal.getTime())){
            JLabel job_label = new JLabel(job.getPark().getName());
            job_label.addMouseListener(new MouseAdapter() {
              @Override
              public void mouseClicked(MouseEvent the_event){
                my_parent.showJob(job);
              }
            });
            day_panel.add(job_label);
          }
          
          my_calendar_days[i][j].add(day_panel, BorderLayout.CENTER);
          my_cal.add(Calendar.DATE, 1);
        } else {
          my_calendar_days[i][j].add(new JLabel(""));
          days_to_skip--;
        }
        my_calendar_days[i][j].setBorder(new LineBorder(Color.BLACK, 2));
        days_panel.add(my_calendar_days[i][j]);
      }
    }
    
  }
  
  /**
   * Change the currently viewed month ahead or behind by one month.
   * 
   * @param forward
   *    true - moves the calendar forward in time one month.
   *    false - moves the calendar backward in time on month.
   */
  private void changeMonth(boolean forward){
    if(!forward){
      my_cal.add(Calendar.MONTH, -2);
    }
    
    String month = (new SimpleDateFormat("MMMM").format(my_cal.getTime()));
    my_current_month.setText(month);
    
    int days_to_skip = getWeekdayNumber(my_cal.get(Calendar.DAY_OF_WEEK));
    int cur_month = my_cal.get(Calendar.MONTH);
    
    for(int i = 0 ; i < 5;i++){
      for(int j = 0; j < 7; j ++){
        my_calendar_days[i][j].removeAll();
        my_calendar_days[i][j].setLayout(new BorderLayout(0,2));
        if(days_to_skip == 0 && cur_month == my_cal.get(Calendar.MONTH)){
          my_calendar_days[i][j].add(new JLabel("" + my_cal.get(Calendar.DATE)), BorderLayout.NORTH);
          
          JPanel day_panel = new JPanel();
          day_panel.setLayout(new BoxLayout(day_panel, BoxLayout.PAGE_AXIS));
          for(final Job job : my_controller.getJobs(my_cal.getTime())){
            JLabel job_label = new JLabel(job.getPark().getName());
            job_label.addMouseListener(new MouseAdapter() {
              @Override
              public void mouseClicked(MouseEvent the_event){
                my_parent.showJob(job);
              }
            });
            day_panel.add(job_label);
          }
          
          my_calendar_days[i][j].add(day_panel, BorderLayout.CENTER);
          
          my_cal.add(Calendar.DATE, 1);
        } else {
          days_to_skip--;
        }
        my_calendar_days[i][j].setBorder(new LineBorder(Color.BLACK, 2));
      }
    }
    
    revalidate();
  }
  
  /**
   * Gets the index (0..6) of the day.
   *  0 - Sunday
   *  1 - Monday
   *  2 - Tuesday
   *  3 - Wednesday
   *  4 - Thursday
   *  5 - Friday
   *  6 - Saturday
   * @param the_day The day constant from the Calendar class.
   * @return The index of the day.
   */
  private int getWeekdayNumber(int the_day){
    int day_index = 0;
    switch(the_day){
    case Calendar.SUNDAY:
      day_index = 0;
      break;
    case Calendar.MONDAY:
      day_index = 1;
      break;
    case Calendar.TUESDAY:
      day_index = 2;
      break;
    case Calendar.WEDNESDAY:
      day_index = 3;
      break;
    case Calendar.THURSDAY:
      day_index = 4;
      break;
    case Calendar.FRIDAY:
      day_index = 5;
      break;
    case Calendar.SATURDAY:
      day_index = 6;
      break;
    }
    return day_index;
  }
  
  /**
   * Action listener for the various buttons.
   */
  @Override
  public void actionPerformed(ActionEvent the_event){
    if(the_event.getSource() == my_next_month_button){
      changeMonth(true);
    } else if (the_event.getSource() == my_prev_month_button){
      changeMonth(false);
    } else if (the_event.getSource() == my_back_button){
      my_parent.back();
    } else if (the_event.getSource() == my_home_button){
      my_parent.home();
    }
  }

}
